/*
	flad : Copyright 2010 Dale J Williams

	Licensed under the Apache License, Version 2.0 (the "License");
	you may not use this file except in compliance with the License.
	You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
*/
package lads.flad.scene.effects {
	
	import flash.display.Sprite;
	
	/**
	 * ParticleEmitter: A base class for emitting particles with control and cleanup.
	 * @author Dale J Williams
	 * @version 1.0
	 */
	public class ParticleEmitter extends Sprite {
		
		private var _type		:Class;
		private var _limit		:int;
		private var _frequency	:int;
		private var _looping	:Boolean;
		private var _frame		:int;
		private var _particles	:Vector.<Particle>;
		private var _playing	:Boolean;
		
		public function ParticleEmitter($type:Class, $limit:int=10, $frequency:int=5, $looping:Boolean=false) {
			if (new $type(this) is Particle == false) 
				throw new Error("Particle Emitter can only accept particles.");
			_type = $type;
			_limit = $limit;
			_frequency = $frequency;
			_looping = $looping;
			init();
		}
		
		private function init():void {
			_particles = new Vector.<Particle>();
		}
		
		public function start():void {
			_playing = true;
			_frame = _frequency;
		}
		
		public function stop($hard:Boolean = false):void {
			if ($hard) removeAll();
			_playing = false;
		}
		
		public function update():void {
			for each(var particle:Particle in _particles) {
				particle.update();
				particle._count();
			}
			if (_frequency-- <= 0) return;
			if (_particles.length < _limit)
				add(new _type(this) as Particle);
			else if (!_looping) stop();
		}
		
		private function add($particle:Particle):void {
			_particles.push($particle);
			addChild($particle);
		}
		
		internal function remove($particle:Particle):void {
			var i:int = _particles.length;
			while (i--) {
				if (_particles[i] == $particle)
					removeChild(_particles.splice(i, 1)[0]);
			}			
		}
		
		private function removeAll():void {
			var i:int = _particles.length;
			while (i--) {
				removeChild(_particles.pop());
			}
		}
		
		public function get limit():int { return _limit; }		
		public function set limit(value:int):void {
			_limit = value;
		}
		
		public function get frequency():int { return _frequency; }		
		public function set frequency(value:int):void {
			_frequency = value;
		}
		
		public function get looping():Boolean { return _looping; }		
		public function set looping(value:Boolean):void {
			_looping = value;
		}
		
		public function get playing():Boolean { return _playing; }
		
	}

}